home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / hurd / hurdpath.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  5KB  |  211 lines

  1. /* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <hurd.h>
  20. #include <string.h>
  21. #include <limits.h>
  22. #include <fcntl.h>
  23.  
  24. error_t
  25. __hurd_path_lookup (file_t crdir, file_t cwdir,
  26.             const char *path, int flags, mode_t mode,
  27.             file_t *result)
  28. {
  29.   error_t err;
  30.   file_t startdir;
  31.  
  32.   enum retry_type doretry;
  33.   char retryname[1024];        /* XXX string_t LOSES! */
  34.   file_t newpt;
  35.   int dealloc_dir;
  36.   int nloops;
  37.  
  38.   if (*path == '/')
  39.     {
  40.       startdir = crdir;
  41.       while (*path == '/')
  42.     ++path;
  43.     }
  44.   else
  45.     startdir = cwdir;
  46.  
  47.   dealloc_dir = 0;
  48.   nloops = 0;
  49.   
  50.   for (;;)
  51.     {
  52.       err = __dir_pathtrans (startdir, (char *) path, flags, mode,
  53.                  &doretry, retryname, result);
  54.  
  55.       if (dealloc_dir)
  56.     __mach_port_deallocate (__mach_task_self (), startdir);
  57.       if (err)
  58.     return err;
  59.  
  60.       switch (doretry)
  61.     {
  62.     case FS_RETRY_NONE:
  63.       /* We got a successful translation.  Now apply any
  64.          open-time action flags we were passed.  */
  65.       if (flags & O_EXLOCK)
  66.         ;            /* XXX */
  67.       if (!err && (flags & O_SHLOCK))
  68.         ;            /* XXX */
  69.       if (!err && (flags & O_TRUNC))
  70.         err = __file_truncate (*result, 0);
  71.  
  72.       if (err)
  73.         __mach_port_deallocate (__mach_task_self (), *result);
  74.       return err;
  75.       
  76.     case FS_RETRY_REAUTH:
  77.       __io_reauthenticate (*result, _hurd_pid);
  78.       __USEPORT (AUTH, __auth_user_authenticate (port, *result, _hurd_pid,
  79.                              &newpt));
  80.       __mach_port_deallocate (__mach_task_self (), *result);
  81.       *result = newpt;
  82.       /* Fall through.  */
  83.  
  84.     case FS_RETRY_NORMAL:
  85. #ifdef SYMLOOP_MAX
  86.       if (nloops++ >= SYMLOOP_MAX)
  87.         return ELOOP;
  88. #endif
  89.  
  90.       if (retryname[0] == '/')
  91.         {
  92.           startdir = crdir;
  93.           dealloc_dir = 0;
  94.           path = retryname;
  95.           do
  96.         ++path;
  97.           while (*path == '/');
  98.         }
  99.       else
  100.         {
  101.           startdir = *result;
  102.           dealloc_dir = 1;
  103.           path = retryname;
  104.         }
  105.       break;
  106.  
  107.     /* case FS_RETRY_MAGICAL: XXX */
  108.     }
  109.     }
  110. }
  111.  
  112. error_t
  113. __hurd_path_split (file_t crdir, file_t cwdir,
  114.            const char *path,
  115.            file_t *dir, char **name)
  116. {
  117.   const char *lastslash;
  118.   error_t err;
  119.   
  120.   /* Skip leading slashes in the pathname.  */
  121.   if (*path == '/')
  122.     {
  123.       while (*path == '/')
  124.     ++path;
  125.       --path;            /* Leave on one slash.  */
  126.     }
  127.   
  128.   lastslash = strrchr (path, '/');
  129.   
  130.   if (lastslash != NULL)
  131.     {
  132.       if (lastslash == path)
  133.     {
  134.       /* "/foobar" => crdir + "foobar".  */
  135.       *name = (char *) path + 1;
  136.       if (err = __mach_port_mod_refs (__mach_task_self (), 
  137.                       crdir, MACH_PORT_RIGHT_SEND, +1))
  138.         return err;
  139.       *dir = crdir;
  140.       return 0;
  141.     }
  142.       else
  143.     {
  144.       /* "/dir1/dir2/.../file".  */
  145.       char dirname[lastslash - path + 1];
  146.       memcpy (dirname, path, lastslash - path);
  147.       dirname[lastslash - path] = '\0';
  148.       *name = (char *) lastslash + 1;
  149.       return __hurd_path_lookup (crdir, cwdir, dirname, 0, 0, dir);
  150.     }
  151.     }
  152.   else
  153.     {
  154.       /* "foobar" => cwdir + "foobar".  */
  155.       *name = (char *) path;
  156.       if (err = __mach_port_mod_refs (__mach_task_self (),
  157.                       cwdir, MACH_PORT_RIGHT_SEND, +1))
  158.     return err;
  159.       *dir = cwdir;
  160.       return 0;
  161.     }
  162. }
  163.  
  164. file_t
  165. __path_lookup (const char *path, int flags, mode_t mode)
  166. {
  167.   error_t err;
  168.   file_t result, crdir, cwdir;
  169.   struct hurd_userlink crdir_ulink, cwdir_ulink;
  170.  
  171.   crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink);
  172.   cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink);
  173.  
  174.   err = __hurd_path_lookup (crdir, cwdir, path, flags, mode, &result);
  175.  
  176.   _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
  177.   _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir);
  178.  
  179.   if (err)
  180.     {
  181.       errno = err;
  182.       return MACH_PORT_NULL;
  183.     }
  184.   else
  185.     return result;
  186. }
  187.  
  188. file_t
  189. __path_split (const char *path, char **name)
  190. {
  191.   error_t err;
  192.   file_t dir, crdir, cwdir;
  193.   struct hurd_userlink crdir_ulink, cwdir_ulink;
  194.  
  195.   crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink);
  196.   cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink);
  197.  
  198.   err = __hurd_path_split (crdir, cwdir, path, &dir, name);
  199.  
  200.   _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
  201.   _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir);
  202.  
  203.   if (err)
  204.     {
  205.       errno = err;
  206.       return MACH_PORT_NULL;
  207.     }
  208.   else
  209.     return dir;
  210. }
  211.